home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include "modern.h"
- #include "zalloc.h"
- #include "zippipe.h"
- #include "zipguts.h"
- #include "ziposcod.h"
- #include "crc32.h"
- #ifndef UNIX
- # ifdef M_XENIX
- # define UNIX
- # endif
- # ifdef unix
- # define UNIX
- # endif
- #endif
- #ifdef UNIX
- # include <time.h>
- #endif
- #ifdef MSDOS
- # include <dos.h>
- #endif
-
- #ifdef __TURBOC__
- #pragma warn -rvl
- #endif
- static unsigned long dostime __ARGS__((void))
- {
- #ifdef MSDOS
- # ifdef __TURBOC__
- /* inline assembly ha-ha! */
- __emit__(/* all arguments must be words to avoid confusion */
- 0x2AB4, /* mov ah,2Ah - get date */
- 0x21CD, /* int 21h */
- 0xE981,1980, /* sub cx,1980 */
- 0xCF88, /* mov bh,cl */
- 0xE7D0, /* shl bh,1 - pack the year in BX */
- 0xD388, /* mov bl,dl - pack the day in BX */
- 0xD230, /* xor dl,dl */
- 0x03B1, /* mov cl,03 */
- 0xEAD3, /* shr dx,cl */
- 0xD309, /* or bx,dx - pack the month -//- */
-
- 0x2CB4, /* mov ah,2Ch get time */
- 0x21CD, /* int 21h */
- 0xC031, /* xor ax,ax */
- 0xCC88, /* mov ah,cl */
- 0x03B1, /* mov cl,3 */
- 0xE8D3, /* shr ax,cl - pack the minutes in AX */
- 0xE5D2, /* shl ch,cl */
- 0xEC08, /* or ah,ch - pack the hours in AX */
- 0xEED0, /* shr dh,1 */
- 0xF008, /* or al,dh - pack the seconds in AX */
-
- 0xDA89); /* mov dx,bx - return value in DX:AX */
- # else
- uninon REGS r;
- unsigned d;
-
- r.h.ah = 0x2A; /* get date */
- intdos(&r,&r);
- d = ((r.x.cx - 1980) << 9) | (r.h.dh << 5) | r.h.dl;
-
- r.h.ah = 0x2C; /* get time */
- intdos(&r,&r);
- return ((unsigned long)d << 16) |
- (r.h.ch << 11) | (r.h.cl << 5) | (r.h.dh >> 1);
- # endif
- #else
- # ifdef UNIX
- extern long time();
- struct tm *s;
- long t;
-
- (void)time(&t);
- s = gmtime(&t);
- if (s->tm_year < 80) return 0L;
- return ((unsigned long)(s->tm_year - 80) << 25) |
- ((unsigned long)s->tm_mon << 21) | ((unsigned long)s->tm_mday << 16) |
- ((unsigned)s->tm_hour << 11) | (s->tm_min << 5) | (s->tm_sec >> 1);
- # else
- /* dummy time stamp */ return 0L;
- # endif
- #endif
- }
- #ifdef __TURBOC__
- #pragma warn .rvl
- #endif
-
- #ifndef zalloc
- /* Turbo C malloc() does not allow dynamic allocation of 64K bytes
- * and farmalloc(64K) returns a pointer with nonzero offset, so we
- * must fix the pointer. Warning: the pointer must be saved in its
- * original form in order to free it, use farfree().
- * For MSC, use halloc instead of this function.
- */
- void far *zalloc(void far **p, unsigned n, unsigned s)
- {
- register unsigned long l;
- l = (unsigned long)(*p = farmalloc((unsigned long)n*s + 15));
- return (void far *)
- ((0xffff0000L & l) + (0xffff0000L & (((0xffffL & l) + 15) << 12)));
- }
- #endif
-
- int zipalloc()
- {
- #ifdef DYN_ALLOC
- if (ct_alloc() != 0) return ZNOMEM;
- if (lm_alloc() != 0) {
- ct_free(); return ZNOMEM;
- }
- #endif
- return 0;
- }
-
- void zipfree()
- {
- #ifdef DYN_ALLOC
- lm_free();
- ct_free();
- #endif
- }
-
- static void putlong __ARGS__((ulg));
-
- static void putlong(l)
- ulg l;
- {
- putword((ush)l); putword((ush)(l >> 16));
- }
-
- static ulg inpsize;
- #ifdef DEBUG
- ulg isize;
- #endif
- static int ziptype;
- int deflate_level = 6;
- static ulg timestamp;
- static ush flags;
-
- /* speed options for the general purpose bit flag */
- #define FAST 4
- #define SLOW 2
-
- int zipcreat(putb, ztype, dlevel)
- void (*putb)__ARGS__((int));
- int ztype, dlevel;
- {
- register k;
-
- if (dlevel<1 || dlevel>9 || (ztype!=ZIP_PKW && ztype!=ZIP_GNU))
- return (ziperror = ZUNSUP);
- deflate_level = dlevel;
- flags = dlevel <= 1 ? FAST : dlevel >= 9 ? SLOW : 0;
- ziptype = ztype;
-
- crcbegin();
- bi_init();
- if (ct_init() != 0) return (ziperror = ZNOMEM);
- if ((k=lm_init()) != 0) {
- #ifdef DYN_ALLOC
- ct_free();
- #endif
- return (ziperror = k);
- }
- ziputbyte = putb;
- /* Write the header to the gzip file */
- /* No extra field, file name or comment; no encryption */
- if (ziptype == ZIP_GNU) {
- putword(GZIP_MAGIC);/* magic header */
- putbyte(DEFLATED); /* compression method */
- putbyte(0); /* general flags: nothing */
- putlong(0L); /* dummy time stamp */
- putbyte(flags); /* extra flags */
- putbyte(OS_CODE); /* OS identifier */
- } else {
- putlong(PKW_LOCAL); /* magic header */
- putword(19); /* version to extract */
- putword(flags|=8);
- putword(DEFLATED); /* compression method */
- /* Who, the hell, needs in this time stamp? */
- putlong(timestamp = dostime());
- putlong(0L); /* dummy CRC */
- putlong(0L); /* dummy compressed size */
- putlong(0L); /* dummy original size */
- putlong(0L); /* null file name & extra fields */
- }
- inpsize = 0L;
- return 0;
- }
-
- int zipwrite(buffer, length)
- char *buffer; unsigned length;
- {
- if (!ziputbyte) return (ziperror=ZNOPEN, -1);
- if (length) {
- updcrc((unsigned char *)buffer, length);
- inpsize += length;
- }
- return deflate_level > 3 ?
- lazy_deflate(buffer, length) :
- fast_deflate(buffer, length);
- }
-
- long zipclose()
- {
- extern unsigned minlookahead;
- register long l = -1;
- ulg clen, crc;
-
- minlookahead = 0; /* indicate end of input */
- /* Flush out any remaining bytes */
- if (zipwrite(NULL,0) != 0) goto end;
- clen = (compressed_len >> 3);
- crc = getcrc();
- if (ziptype == ZIP_GNU) {
- /* Write the crc. & uncompressed size */
- putlong(crc); putlong(inpsize);
- } else {
- /* Write the /data descriptor/ extended locxal header */
- putlong(PKW_EXT); /* signature */
- putlong(crc); /* CRC */
- putlong(clen); /* compressed size */
- putlong(inpsize); /* uncompressed size */
- /* Write the central directory entry */
- putlong(PKW_CENTRAL);
- putword((OS_CODE<<8)|20); /* version made by */
- putword(19); /* version to extract */
- putword(flags);
- putword(DEFLATED);/* compression method */
- putlong(timestamp);
- putlong(crc); /* CRC */
- putlong(clen); /* compressed size */
- putlong(inpsize); /* original size */
- putlong(0L); /* filename & extra field length */
- putword(0); /* file comment length */
- putword(0); /* disk number start */
- putword(0); /* internal file attributes */
- putlong(0L); /* external file attributes */
- putlong(0L); /* relative offset of local header */
- /* Finish the central directory */
- putlong(PKW_END);
- putword(0); /* number of this disk */
- putword(0); /* number of the disk with the start of CD */
- putword(1); /* total number of CD entries on this disk */
- putword(1); /* total number of CD entries */
- putlong(46L); /* size of the central directory */
- putlong(30+clen+16); /* offset of start of CD */
- putword(0); /* zipfile comment length */
- }
- l = clen;
- end:
- ziputbyte = NULL;
- zipfree();
- return l;
- }